package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.interfaces.BAreaService;
import cn.huiyunche.base.service.interfaces.BCitiesDistanceService;
import cn.huiyunche.base.service.mappers.BCitiesDistanceMapper;
import cn.huiyunche.base.service.mappers.ext.BCitiesDistanceViewMapper;
import cn.huiyunche.base.service.model.BArea;
import cn.huiyunche.base.service.model.BCitiesDistance;
import cn.huiyunche.base.service.model.BCitiesDistanceExample;
import cn.huiyunche.base.service.vo.BCitiesDistanceVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.Result;
import com.alibaba.fastjson.JSON;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BCitiesDistanceServiceImpl implements BCitiesDistanceService {

    private static final Logger LOGGER = LoggerFactory.getLogger(BCitiesDistanceServiceImpl.class);

    @Autowired
    private BCitiesDistanceMapper citiesDistanceMapper;

    @Autowired
    private BCitiesDistanceViewMapper bCitiesDistanceViewMapper = null;

    @Autowired
    private BAreaService areaService = null;

    public BCitiesDistanceMapper getBCitiesDistanceMapper() {
        return this.citiesDistanceMapper;
    }

    public BCitiesDistanceViewMapper getBCitiesDistanceViewMapper() {
        return this.bCitiesDistanceViewMapper;
    }

    public BAreaService getAreaService() {
        return this.areaService;
    }

    /**
     * 城市运距列表
     */
    @Override
    public Map<String, Object> list(PageVo page, BCitiesDistanceVo bCitiesDistanceVo2) {
        LOGGER.info("select city distance list params : {}.", JSON.toJSONString(bCitiesDistanceVo2));
        Map<String, Object> map = new HashMap<String, Object>();
        List<BCitiesDistanceVo> voList = new ArrayList<BCitiesDistanceVo>();
        try {
            BCitiesDistanceExample example = new BCitiesDistanceExample();
            example.setLimitStart(page.getStartIndex());
            example.setLimitEnd(page.getPageSize());
            if (StringUtils.isNotBlank(page.getOrder())) {
                example.setOrderByClause(page.getOrder());
            } else {
                example.setOrderByClause("id DESC");
            }

            // 省份查询条件
            String firstProCode = bCitiesDistanceVo2.getFirstProCode();
            if (StringUtils.isNotBlank(firstProCode)) {
                // 城市code 查询条件
                String firstCityCode = bCitiesDistanceVo2.getFirstCityCode();
                if (StringUtils.isNotBlank(firstCityCode)) {
                    example.createCriteria().andFirstCityCodeEqualTo(firstCityCode);

                    BCitiesDistanceExample example2 = new BCitiesDistanceExample();
                    BCitiesDistanceExample.Criteria createCriteria = example2.createCriteria();
                    createCriteria.andSecondCityCodeEqualTo(firstCityCode);

                    example.or(createCriteria);
                } else {
                    // 查询省下所有的市code
                    List<BArea> areas = this.getAreaService().selectAreaByParentCode(firstProCode);
                    List<String> codes = new ArrayList<String>();
                    for (BArea bArea : areas) {
                        codes.add(bArea.getCode());
                    }
                    example.createCriteria().andFirstCityCodeIn(codes);

                    BCitiesDistanceExample example2 = new BCitiesDistanceExample();
                    BCitiesDistanceExample.Criteria createCriteria = example2.createCriteria();
                    createCriteria.andSecondCityCodeIn(codes);

                    example.or(createCriteria);
                }
            }

            page.setTotalRecord(this.getBCitiesDistanceMapper().countByExample(example));
            List<BCitiesDistanceVo> list = this.getBCitiesDistanceViewMapper().selectByExample(example);
            for (BCitiesDistanceVo bCitiesDistanceVo : list) {
                LOGGER.info("select city distance list proname cityname.");
                if (null != bCitiesDistanceVo.getFirstCityCode()) {
                    BArea cityBArea = this.getAreaService().selectAreaByCodeAndLevel(bCitiesDistanceVo.getFirstCityCode(), 2 + "");
                    BArea bArea = this.getAreaService().selectAreaByCodeAndLevel(cityBArea.getParentCode(), 1 + "");
                    // BArea bArea = this.getAreaService().selectProByCityCode(bCitiesDistanceVo.getFirstCityCode());
                    bCitiesDistanceVo.setFirstCityName(cityBArea.getName());
                    bCitiesDistanceVo.setFirstProCode(bArea.getCode());
                    bCitiesDistanceVo.setFirstProName(bArea.getName());
                    LOGGER.info("select city distance list proname:{}, cityname:{}.", bArea.getName(), cityBArea.getName());

                    BArea sCityBArea = this.getAreaService().selectAreaByCodeAndLevel(bCitiesDistanceVo.getSecondCityCode(), 2 + "");
                    BArea sbArea = this.getAreaService().selectAreaByCodeAndLevel(sCityBArea.getParentCode(), 1 + "");
                    // BArea sbArea = this.getAreaService().selectProByCityCode(bCitiesDistanceVo.getSecondCityCode());
                    bCitiesDistanceVo.setSecondCityName(sCityBArea.getName());
                    bCitiesDistanceVo.setSecondProCode(sbArea.getCode());
                    bCitiesDistanceVo.setSecondProName(sbArea.getName());
                    LOGGER.info("select city distance list proname:{}, cityname:{}.", sbArea.getName(), sCityBArea.getName());

                    voList.add(bCitiesDistanceVo);
                }
            }

            map.put("page", page);
            map.put("cityDistances", voList);
        } catch (Exception e) {
            LOGGER.error("select city distance list error : {}.", e);
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 更新城市运距
     */
    @Override
    public Result<String> updateCityDistance(BCitiesDistance bCitiesDistance) {
        LOGGER.info("updateCityDistance param : {}", bCitiesDistance);
        Result<String> result = new Result<String>(true, null, "更新城市运距成功");
        /** if(StringUtils.isNotBlank(bCitiesDistance.getFirstCityCode())){
         logger.info("udpate city distance firstcitycode is not null.");
         result.setSuccess(false);
         result.setMessage("起始城市code不能为空");
         return result;
         } else if(StringUtils.isNotBlank(bCitiesDistance.getSecondCityCode())){
         logger.info("update city distance secondcitycode is not null");
         result.setSuccess(false);
         result.setMessage("目的城市code不能为空");
         return result;
         } */
        if (bCitiesDistance.getId() == null) {
            LOGGER.info("update city distance id is not null");
            result.setSuccess(false);
            result.setMessage("更新城市运距ID不能为空");
            return result;
        } else if (bCitiesDistance.getDistance() == null) {
            LOGGER.info("update city distance is not null");
            result.setSuccess(false);
            result.setMessage("运距不能为空");
            return result;
        }

        try {
            result.setData(this.getBCitiesDistanceMapper().updateByPrimaryKeySelective(bCitiesDistance) + "");
        } catch (Exception e) {
            LOGGER.error("update city distance error :{}.", e);
            result.setSuccess(false);
            result.setMessage("更新城市运距系统异常");
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public Long add(String firstCityCode, String secondCityCode, BigDecimal distance) {
        LOGGER.info("add params : {}, {}, {}", firstCityCode, secondCityCode, distance);
        if (StringUtils.isBlank(firstCityCode)) {
            LOGGER.error("add firstCityCode must not be null");
            throw new IllegalArgumentException("firstCityCode must not be null");
        }
        if (StringUtils.isBlank(secondCityCode)) {
            LOGGER.error("secondCityCode must not be null");
            throw new IllegalArgumentException("secondCityCode must not be null");
        }
        if (distance == null) {
            LOGGER.error("distance must not be null");
            throw new IllegalArgumentException("distance must not be null");
        }

        //查询是否已经存在，存在则不添加
        BigDecimal decimal = this.getDistanceByCitiesCode(firstCityCode, secondCityCode);
        if (null != decimal) {
            return null;
        }

        BCitiesDistance cd = new BCitiesDistance();
        cd.setFirstCityCode(firstCityCode);
        cd.setSecondCityCode(secondCityCode);
        cd.setDistance(distance);
        citiesDistanceMapper.insertSelective(cd);
        return cd.getId();
    }

    @Override
    public BigDecimal getDistanceByCitiesCode(String firstCityCode, String secondCityCode) {
        LOGGER.info("getDistanceByCitiesCode params : {}, {}", firstCityCode, secondCityCode);
        if (StringUtils.isBlank(firstCityCode)) {
            LOGGER.error("firstCityCode must not be null");
            throw new IllegalArgumentException("firstCityCode must not be null");
        }
        if (StringUtils.isBlank(secondCityCode)) {
            LOGGER.error("secondCityCode must not be null");
            throw new IllegalArgumentException("secondCityCode must not be null");
        }
        BCitiesDistanceExample example = new BCitiesDistanceExample();
        BCitiesDistanceExample.Criteria criteria1 = example.createCriteria();
        BCitiesDistanceExample.Criteria criteria2 = example.createCriteria();
        criteria1.andFirstCityCodeEqualTo(firstCityCode).andSecondCityCodeEqualTo(secondCityCode);
        criteria2.andFirstCityCodeEqualTo(secondCityCode).andSecondCityCodeEqualTo(firstCityCode);
        example.or(criteria2);
        List<BCitiesDistance> list = citiesDistanceMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0).getDistance();
        }
        return null;
    }

}
